/*
 * Copyright 2010 Brian Watkins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package bw.os;

import bw.util.*;
import com.google.appengine.api.datastore.*;
import javax.servlet.*;
import java.io.*;
import java.util.*;

public class GoogleDatastoreHandler extends PersistentObjectHandler
    implements PersistentObjectReader, PersistentObjectWriter
{
    public static final String WD_OBJECT_KIND = "wd-object";
    public static final String WD_OBJECT_NAME = "name";
    public static final String WD_OBJECT_DATA = "data";

    public GoogleDatastoreHandler ( ServletContext context )
    {
        Log.getInstance().write( "Google Datastore Service Initialized!" );
    }

    // READER methods

    public Hashtable readAll () throws Exception
    {
        Hashtable objects = new Hashtable();

        PreparedQuery query = service().prepare( new Query( WD_OBJECT_KIND ) );
        Iterator entities = query.asIterator();
        while ( entities.hasNext() )
        {
            Entity entity = (Entity) entities.next();
            String key = (String) entity.getProperty( WD_OBJECT_NAME );
            
            Blob b = (Blob) entity.getProperty( WD_OBJECT_DATA );            
            Object obj = getObjectFromStream( new ByteArrayInputStream( b.getBytes() ) );

            objects.put( key, obj );
        }

        return objects;
    }

    public Object read ( String key ) throws Exception
    {
        Key ds_key = KeyFactory.createKey( WD_OBJECT_KIND, key );

        //Log.getInstance().write( "Reading key: " + ds_key );

        Entity entity = null;
        try
        {
            entity = service().get( ds_key );
        }
        catch ( EntityNotFoundException ex )
        {
            //Log.getInstance().write( "Entity not found for key: " + ds_key.toString() );
        }

        Object obj = null;

        if ( entity != null )
        {
            Blob b = (Blob) entity.getProperty( WD_OBJECT_DATA );            
            obj = getObjectFromStream( new ByteArrayInputStream( b.getBytes() ) );
        }

        return obj;
    }

    // WRITER methods

    public void write ( String key, Object obj ) throws Exception
    {
        Key ds_key = KeyFactory.createKey( WD_OBJECT_KIND, key );
        
        //Log.getInstance().write( "Writing key: " + ds_key );

        Entity entity = new Entity( ds_key );
        entity.setProperty( WD_OBJECT_NAME, key );

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        ObjectOutputStream oos = getObjectOutputStream( bytes );
        oos.writeObject( obj );
        oos.close();

        entity.setProperty( WD_OBJECT_DATA, new Blob( bytes.toByteArray() ) );

        service().put( entity );
    }

    public void erase ( String key ) throws Exception
    {
        Key ds_key = KeyFactory.createKey( WD_OBJECT_KIND, key );

        //Log.getInstance().write( "Erasing key: " + ds_key );

        service().delete( ds_key );
    }

    private DatastoreService service ()
    {
        return DatastoreServiceFactory.getDatastoreService();
    }

    public void shutdown () throws Exception
    {

    }
}